package com.zzyl.nursing.service.impl;

import java.util.List;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zzyl.common.utils.DateUtils;
import com.zzyl.nursing.domain.Bed;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.BedMapper;
import com.zzyl.nursing.mapper.ElderMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.nursing.mapper.CheckInMapper;
import com.zzyl.nursing.domain.CheckIn;
import com.zzyl.nursing.service.ICheckInService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import javax.swing.text.html.parser.Entity;
import java.util.Arrays;

/**
 * 老人入住Service业务层处理
 *
 * @author 王 月峰
 * @date 2025-07-25
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;
    @Autowired
    private ElderMapper elderMapper;
    @Autowired
    private BedMapper bedMapper;

    /**
     * 查询老人入住
     *
     * @param id 老人入住主键
     * @return 老人入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询老人入住列表
     *
     * @param checkIn 老人入住
     * @return 老人入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增老人入住
     *
     * @param checkIn 老人入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改老人入住
     *
     * @param checkIn 老人入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除老人入住
     *
     * @param ids 需要删除的老人入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除老人入住信息
     *
     * @param id 老人入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }

    //入住申请
    //applyDto 前端传入的所有参数
    @Override
    //applydto 包含所有值
    public void apply(CheckInApplyDto applyDto) {
        //1．校验老人是否已入住，根据身份证查，看老人入住的状态是否为1
        LambdaQueryWrapper<Elder> elderQueryWrapper = new LambdaQueryWrapper<>();
        /*LambdaQueryWrapper<Elder> objectLambdaQueryWrapper = new LambdaQueryWrapper<>();*/
        elderQueryWrapper.eq(Elder::getIdCardNo, applyDto.getCheckInElderDto().getIdCardNo());
        /*objectLambdaQueryWrapper.eq(Elder::getIdCardNo , applyDto.getCheckInElderDto().getIdCardNo());*/
        /*objectLambdaQueryWrapper.eq(Elder::getStatus , 1);*/

        //查看老人表中的老人状态是否为入住 = 1 elder 得到老人的对象
        elderQueryWrapper.eq(Elder::getStatus, 1);
        //如果数据库中有符合条件的记录，就会返回第一个匹配的Elder对象；如果没有匹配的记录，则返回null。
        //所以这行代码的作用就是根据身份证号查询该老人是否已经处于入住状态，用于后续判断是否允许办理入住手续
       /* elderQueryWrapper 包含了两个查询条件：
        身份证号匹配
        状态为已入住（status=1）
        当执行 elderMapper.selectOne(elderQueryWrapper) 时，MyBatis-Plus 会将这些条件转换为 SQL 查询语句，类似
        SELECT * FROM elder WHERE id_card_no = ? AND status = 1 LIMIT 1*/
        Elder elder = elderMapper.selectOne(elderQueryWrapper);
        //判断老人信息表中的新来的老人是否为null，是的话-->添加信息，-->更改信息。
        //因为返回值是void 所以抛异常给前端 如果老人的表中有该老人/不为空的话，则抛出异常给前端
        if (ObjectUtil.isNotEmpty(elder)) {
            throw new RuntimeException("该老人已入住");
        }
        //2．更新床位状态为已入住
        //如果1条件不成立的话 == 之前来过 == 更新床位状态为已入住
        //查询配置 这张表里面的床位getCheckInConfigDto 入住配置表 --> getBedId()床位信息
        Bed bed = bedMapper.selectById(applyDto.getCheckInConfigDto().getBedId());
        //把这个床位设置成1的状态，代表床位已入住
        bed.setBedStatus(1);
        //更新床的状态为已入住
        bedMapper.updateById(bed);
        //3．新增或更新老人
        //创建方法 将床位信息传递给insertOrUpdateElder方法的原因是：为了在新增或更新老人信息时，同时将分配的床位信息（床位号和床位ID）保存到老人记录中，建立老人与床位的关联关系。
        //这样可以确保系统能够追踪每个老人分配的床位，便于后续的床位管理和入住情况查询。
        Elder elder1 = insertOrUpdateElder(applyDto.getCheckInElderDto(), bed);
        //4．新增签约办理
        //5．新增入住信息
        //6．新增入住配置
        //7．保存老人家属信息

    }

    /**
     * 新增或更新老人信息
     *
     * @param checkInElderDto 入住信息
     * @param bed             床位信息
     */
    private Elder insertOrUpdateElder(CheckInElderDto checkInElderDto, Bed bed) {
        //因为是新增或者更新，所以用eldermapper老人mapper层使用 updateById方法/insert方法
        Elder e = new Elder();
        BeanUtils.copyProperties(checkInElderDto, e);
        //4，因为老人表里面没有床位信息和床位编号，所以我们手动赋值给e，
        // 老人表里面，并且刚才又更新了床位状态Status，所以里面也要添加已入住Status = 1
        //给e -->床位信息,床位编号,Status = 1
        e.setBedId(bed.getId());
        e.setBedNumber(bed.getBedNumber());
        e.setStatus(1);

        //是新增还是修改 --> 查询数据 查到的话就是新增 没查到就是修改
        LambdaQueryWrapper<Elder> elderQueryWrapper = new LambdaQueryWrapper<>();
        elderQueryWrapper.eq(Elder::getIdCardNo, checkInElderDto.getIdCardNo());
        elderQueryWrapper.eq(Elder::getStatus, 1);
        Elder elder = elderMapper.selectOne(elderQueryWrapper);

        if (ObjectUtil.isNotEmpty(elder)) {
            //查询结果已存在 ： 修改
            elderMapper.updateById(e);
        } else {
            //查询结果不存在 ： 新增
            elderMapper.insert(e);
        }
        return e;
    }

}
